package MyArrayList;
// 泛型方式, 写起来更麻烦一些. 未来面试的时候, 一般也都不要写泛型版本的.
public class MyArrayList {
    private String[] data=null;
    private int size=0;
    public MyArrayList() {
         data = new String[10];
    }
    public MyArrayList(int capacity){
        if (capacity<=10){
            capacity=10;
        }
        data=new String[capacity];
    }


    //实现扩容操作
    private void resize() {
        //创建更长的数组，新的数组容量是原来的1.5倍
        String[] newData=new String[data.length+(data.length>>1)];
        //把旧数组的元素，复制到新数组上
        for (int i=0;i<size;i++){
            newData[i]=data[i];
        }
        //用新数组代替旧数组
        data=newData;
    }

    //实现添加元素的操作
    public void add(String element){
        if (size>=data.length){
            resize();
        }
        data[size]=element;
        size++;//size为顺序表的大小
    }
    public String toString() {
        //把有效元素转为字符串，并拼接到一起
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append("[");
        for (int i=0;i<size;i++){
            stringBuilder.append(data[i]);
            if (i<size-1){
                //如果i是size-1，则说明最后一个元素，不需要加逗号了
                stringBuilder.append(",");
            }
        }
        stringBuilder.append("]");
        return stringBuilder.toString();
    }

    //向中间插入元素
    public void add(int index,String elem){
        //判断index是否合法
        //index为0相当于头插
        //index为size，相当于尾插
        if (index<0||index>size){
            throw new IndexOutOfBoundsException("index:"+index+",Size:"+size);
        }
        if (size>= data.length){
            resize();
        }
        for (int i=size-1;i>=index;i--){
            data[i+1]=data[i];
        }
        data[index]=elem;
        size++;//size为
    }

    //按照下表删除元素
    //返回被删除元素的值
    public String remove(int index){
        if (index<0||index>=size){
            throw new IndexOutOfBoundsException("index:"+index+",Size:"+size);
        }
        //先将删除的元素的值保存一份，后面搬运的时候会被覆盖
        String elem=data[index];
        for (int i=index;i<size-1;i++){
            data[i]=data[i+1];
        }
        size--;
        return elem;
    }

    //按照元素的值来删除
    //如果删除成功，返回true
    //如果elem本身不存在，就认为是删除失败
    public boolean remove(String elem){
        //先找到elem队形的位置
        int remobePos=0;
        for (;remobePos<size;remobePos++){
            if (data[remobePos].equals(elem)){
                break;
            }
        }
        //上述循环结束，有两种可能1.找到elem，2.没有找到elem，i和size相等
        if (remobePos==size){
            return false;
        }
        //用remobePos下表来进行删除
        remove(remobePos);
        return true;
    }

    public String get(int index) {
        if (index<0||index>=size){
            throw new IndexOutOfBoundsException("index:"+index+",Size:"+size);
        }
        return data[index];
    }
    public void set(int index,String elem) {
        if (index < 0 || index > size){
            throw new IndexOutOfBoundsException("index:"+index+",Size:"+size);
        }
       data[index]=elem;
    }

    //删除所有的元素
    public void clear(){
        size=0;
    }

    public int indexOf(String elem){
        for (int i=0;i<size;i++){
            if (data[i].equals(elem)){
                return i;
            }
        }
        return -1;
    }

    //判断elem元素是否存在
    public boolean contains(String elem){
//        for (int i=0;i<size;i++){
//            if (data[i].equals(elem)){
//                return true;
//            }
//        }
//        return false;
        return indexOf(elem)!=-1;
    }

    //[fromIndex,toIndex)区间的元素
    public MyArrayList subList(int fromIndex, int toIndex){
        //创建一个新的MyArrayList对象，把上述区间的元素2，添加到新的对象中即可
        //注意边界值，fromIndex如果为0，是合法情况，toIndex如果为size，也是合法情况
        //froIndex==toIndex，也是合法的，得到空的区间
        if (fromIndex<0||fromIndex>toIndex||toIndex>size){
            throw new IndexOutOfBoundsException("fromIndex:"+fromIndex+",toIndex:"+toIndex+",Size:"+size);
        }
        MyArrayList list = new MyArrayList();
        for (int i=fromIndex;i<toIndex;i++){
            String elem=this.get(i);
            list.add(elem);
        }
        return list;
    }

    public static void test1(){
        MyArrayList list=new MyArrayList();
        list.add("hello");
        list.add("world");
        list.add("world");
        list.add("world");
        list.add("world");
        list.add("world");
        list.add("world");
        list.add("world");
        list.add("world");
        list.add("world");
        list.add("world");
        list.add("world");
        System.out.println(list);
    }

    //测试中间位置插入
    private static void test2(){
        MyArrayList list = new MyArrayList();
        list.add(0,"aaa");
        list.add(0,"bbb");
        list.add(0,"ccc");
        list.add(0,"ddd");
        list.add(0,"eee");
        System.out.println(list);
    }

    //测试删除操作
    private static void test3(){
        MyArrayList list = new MyArrayList();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");
        String elem=list.remove(1);
        System.out.println(elem);
        System.out.println(list);
    }
    private static void test4(){
        MyArrayList list = new MyArrayList();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");
        boolean ret =list.remove("aa");
        System.out.println(ret);
        System.out.println(list);
    }
    private static void test5(){
        MyArrayList list = new MyArrayList();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        System.out.println(list.contains("aa"));
    }
    public static void test6() {
        MyArrayList list = new MyArrayList();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");
        System.out.println(list.indexOf("cc"));
    }
    public static void test7(){
        MyArrayList list = new MyArrayList();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");
        System.out.println(list.subList(1,3));
    }
    public static void main(String[] args) {
//        test1();
//        test2();
//        test3();
//        test4();
//        test5();
//        test6();
        test7();
    }
}
